package com.itheima.utils;

import org.apache.ibatis.io.Resources;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;

import java.io.IOException;
import java.io.InputStream;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;

public class MybatisUtils {

    private MybatisUtils() {
    }

    private static SqlSessionFactory factory;

    static {
        try {
            InputStream in = Resources.getResourceAsStream("MyBatisConfig.xml");
            factory = new SqlSessionFactoryBuilder().build(in);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }


    /**
     * 获取SqlSession对象
     *
     * @return
     */
    public static SqlSession getSqlSession() {
        return factory.openSession();
    }


    /*
        获取指定dao接口代理对象
     */
    public static Object getMapper(Class daoClass){
        //1. 获取SqlSession
        SqlSession sqlSession = getSqlSession();
        //2. 基于框架获取dao代理对象
        Object mapper = sqlSession.getMapper(daoClass);

        //3. 对象框架获取dao代理对象 进行方法增强
        Object proxy_mapper = Proxy.newProxyInstance(mapper.getClass().getClassLoader(), new Class[]{daoClass}, new InvocationHandler() {
            @Override
            public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
                Object value = null;

                try {
                    //对原始方法进行调用
                    value = method.invoke(mapper, args);
                    //成功: 提交事务
                    sqlSession.commit();
                } catch (Exception e) {
                    e.printStackTrace();
                    //失败: 回滚事务
                    sqlSession.rollback();
                }  finally {
                    // 释放资源
                    sqlSession.close();
                }
                return value;
            }
        });

        //4. 返回代理对象
        return proxy_mapper;

    }
}
